import typing
from enum import Enum
from pprint import pprint
from typing import List, Dict
import pandas as pd
import numpy as np
import os
import datetime
import logging

logger = logging.Logger(name="ReportGeneratorLogger")


def abspath(path: str):
    return os.path.expanduser(os.path.abspath(path))


class Report:
    """
    统计数据并生成报告
    """

    def __init__(self):
        self.total_cnt: int = 0
        self.consult_cnt: int = 0
        self.request_cnt: int = 0
        self.bug_cnt: int = 0
        self.vulnerability_cnt: int = 0
        self.processing_total: int = 0
        self.current_week_processing: int = 0
        self.current_week_total: int = 0
        self.current_week_consult: int = 0
        self.current_week_bug: int = 0
        self.current_week_request: int = 0
        self.current_week_vulnerability: int = 0
        self.sla: int = 0
        self.app_cnt: int = 0
        self.app_list: List[str] = list()

    def __add__(self, other):
        other: Report = other
        self.total_cnt += other.total_cnt
        self.consult_cnt += other.consult_cnt
        self.request_cnt += other.request_cnt
        self.bug_cnt += other.bug_cnt
        self.vulnerability_cnt += other.vulnerability_cnt
        self.processing_total += other.processing_total
        self.current_week_processing += other.current_week_processing
        self.current_week_total += other.current_week_total
        self.current_week_consult += other.current_week_consult
        self.current_week_bug += other.current_week_bug
        self.current_week_request += other.current_week_request
        self.current_week_vulnerability += other.current_week_vulnerability
        self.sla += other.sla
        self.app_cnt += other.app_cnt
        self.app_list.extend(other.app_list)
        return self

    def __str__(self):
        result: str = f"{self.app_cnt}个应用({str(self.app_list)})，ir单总量：{self.total_cnt}，咨询/bug/需求/漏洞：{self.consult_cnt}/{self.bug_cnt}/{self.request_cnt}/{self.vulnerability_cnt}；" \
                      f"其中，本周新增:{self.current_week_total}，咨询/bug/需求/漏洞：{self.current_week_consult}/{self.current_week_bug}/{self.current_week_request}/{self.current_week_vulnerability}；" \
                      f"未闭环总量：{self.processing_total};本周未闭环：{self.current_week_processing}；" \
                      f"总闭环率：{round(((self.total_cnt - self.processing_total) / self.total_cnt) * 100, 2) if self.total_cnt != 0 else 100}%；" \
                      f"本周闭环率：{round(((self.current_week_total - self.current_week_processing) / self.current_week_total) * 100, 2) if self.current_week_total != 0 else 100}%；" \
                      f"超期：{self.sla}"
        return result


class Generator:
    """
    处理导出的数据并利用Report生成报告
    """

    def __init__(self, excel_directory: str = "./export_files", days: int = 7):
        self.folder = abspath(excel_directory)
        if not os.path.isdir(self.folder):
            raise Exception(f"directory {self.folder} is not valid")
        self.dt_format: str = "%Y-%m-%d %H:%M:%S"
        self.files: List[str] = [os.path.join(self.folder, x) for x in os.listdir(self.folder)]
        self.now = datetime.datetime.now()
        self.last_week = (self.now - datetime.timedelta(days=days)).strftime(self.dt_format)
        self.report = Report()
        self.report_list: List[Report] = list()

    def save(self, excel_name: str = "issuereporter_report.xlsx", sheet_name: str = "统计"):
        header: List[str] = ["应用名称", "ir单总量", "本周新增", "总量：需求/咨询/bug/漏洞",
                             "本周：需求/咨询/bug/漏洞", "总量：处理中", "本周：处理中", "总闭环率", "本周闭环率", "超期（处理中）"]
        data: List[List] = list()
        rl: List[Report] = [self.report] + self.report_list
        for rpt in rl:
            app_name: str = "汇总" if rl.index(rpt) == 0 else rpt.app_list[0]
            row: List = [app_name, rpt.total_cnt, rpt.current_week_total,
                         f"{rpt.request_cnt}/{rpt.consult_cnt}/{rpt.bug_cnt}/{rpt.vulnerability_cnt}",
                         f"{rpt.current_week_total}/{rpt.current_week_consult}/{rpt.bug_cnt}/{rpt.vulnerability_cnt}",
                         f"{rpt.processing_total}", f"{rpt.current_week_processing}",
                         f"{round(((rpt.total_cnt - rpt.processing_total) / rpt.total_cnt) * 100, 2) if rpt.total_cnt != 0 else 100}",
                         f"{round(((rpt.current_week_total - rpt.current_week_processing) / rpt.current_week_total) * 100, 2) if rpt.current_week_total != 0 else 100}",
                         f"{rpt.sla}"]
            data.append(row)
        df: pd.DataFrame = pd.DataFrame(np.array(data))
        df.to_excel(excel_name, sheet_name=sheet_name, header=header)

    def __process_excel__(self, excel_path: str):
        file_abs_path: str = abspath(excel_path)
        if not os.path.isfile(file_abs_path):
            raise FileNotFoundError(f"file {excel_path} is not valid")
        df: pd.DataFrame = pd.read_excel(file_abs_path)
        app_name: str = os.path.split(excel_path)[-1].split(".")[0]
        rpt: Report = Report()
        rpt.app_list.append(app_name)

        rpt.total_cnt = df.shape[0]
        rpt.request_cnt = df[df["类型"] == "需求"].shape[0]
        rpt.consult_cnt = df[df["类型"] == "咨询"].shape[0]
        rpt.bug_cnt = df[df["类型"] == "bug"].shape[0]
        rpt.vulnerability_cnt = df[df["类型"] == "漏洞"].shape[0]
        rpt.processing_total = df[df["状态"] == "处理中"].shape[0]
        rpt.sla = df[df["状态"] == "处理中"][df[df["状态"] == "处理中"]["问题闭环超期时长"].isnull() == False].shape[0]

        current_week_all = df[df["创建时间(UTC)"] > self.last_week]

        rpt.current_week_total += current_week_all.shape[0]
        rpt.current_week_request += current_week_all[current_week_all["类型"] == "需求"].shape[0]
        rpt.current_week_consult += current_week_all[current_week_all["类型"] == "咨询"].shape[0]
        rpt.current_week_bug += current_week_all[current_week_all["类型"] == "bug"].shape[0]
        rpt.current_week_vulnerability += current_week_all[current_week_all["类型"] == "漏洞"].shape[0]
        rpt.current_week_processing += current_week_all[current_week_all["状态"] == "处理中"].shape[0]
        rpt.app_cnt += 1
        self.report = self.report + rpt
        self.report_list.append(rpt)

    def generate(self):
        for item in self.files:
            try:
                self.__process_excel__(item)
            except FileNotFoundError:
                logger.error(f"file {item} not found")
            except Exception:
                logger.error(f"processing {item} failed")
        pprint(str(self.report))
        for rpt in self.report_list:
            pprint(str(rpt))
        return self


class IssueReporterFilters:
    def __init__(self, excel: str):
        self.file = abspath(excel)
        self.pure_dir, self.pure_file = os.path.split(self.file)
        if not os.path.isfile(self.file):
            raise FileExistsError(f"file {self.file} not exists")
        self.df: pd.DataFrame = pd.read_excel(self.file)

    def save(self, data: pd.DataFrame, key: str, value: str):
        data.to_excel(os.path.join(self.pure_dir, f"{key}_{value}_{self.pure_file}"))

    def gt(self, key: str, value: str):
        data = self.df[self.df[key] > value]
        self.save(data, key, "gt")

    def eq(self, key: str, value: str):
        data = self.df[self.df[key] == value]
        self.save(data, key, value)


g = Generator()
g.generate().save()

# irf = IssueReporterFilters("./export_files/支付宝.xlsx")
# # irf.eq("状态", "处理中")
# irf.gt("创建时间(UTC)", "2023-09-11 00:00:00")
